<!DOCTYPE html>
<html>
<head>
    <title>Thermodynamics Diagram</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            background-color: #f0f0f0;
        }
        canvas {
            border: 1px solid #ccc;
            background-color: #fff;
        }
    </style>
</head>
<body>
    <canvas id="physicsCanvas" width="750" height="500"></canvas>
    <script>
        const canvas = document.getElementById('physicsCanvas');
        const ctx = canvas.getContext('2d');

        // Style settings
        ctx.lineWidth = 2;
        ctx.strokeStyle = '#000';
        ctx.fillStyle = '#000';
        ctx.font = "24px Songti SC, serif"; // Use a common serif font
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';

        // --- Drawing functions ---

        // Function to draw the main arrow for the atomic beam
        function drawBeamArrow(ctx, fromX, fromY, toX, toY, headLength) {
            const angle = Math.atan2(toY - fromY, toX - fromX);
            
            // Main line
            ctx.beginPath();
            ctx.moveTo(fromX, fromY);
            ctx.lineTo(toX, toY);
            
            // Arrowhead
            ctx.lineTo(toX - headLength * Math.cos(angle - Math.PI / 6), toY - headLength * Math.sin(angle - Math.PI / 6));
            ctx.moveTo(toX, toY);
            ctx.lineTo(toX - headLength * Math.cos(angle + Math.PI / 6), toY - headLength * Math.sin(angle + Math.PI / 6));
            
            ctx.stroke();
        }

        // --- Draw components ---

        // 1. Source Chamber (left box)
        const sourceBox = { x: 50, y: 160, w: 160, h: 110 };
        ctx.strokeRect(sourceBox.x, sourceBox.y, sourceBox.w, sourceBox.h);
        ctx.fillText("1 000 °C", sourceBox.x + sourceBox.w / 2, sourceBox.y + sourceBox.h / 2);

        // 2. Vacuum Chamber (right box)
        const vacuumBox = { x: 300, y: 120, w: 380, h: 200 };
        ctx.strokeRect(vacuumBox.x, vacuumBox.y, vacuumBox.w, vacuumBox.h);
        ctx.fillText("300 K", vacuumBox.x + vacuumBox.w / 2, vacuumBox.y + 30);
        
        // Vertical text "真空容器"
        const verticalTextX = vacuumBox.x + vacuumBox.w + 30;
        const verticalTextYStart = vacuumBox.y + 60;
        const verticalTextSpacing = 30;
        ctx.fillText("真", verticalTextX, verticalTextYStart);
        ctx.fillText("空", verticalTextX, verticalTextYStart + verticalTextSpacing);
        ctx.fillText("容", verticalTextX, verticalTextYStart + 2 * verticalTextSpacing);
        ctx.fillText("器", verticalTextX, verticalTextYStart + 3 * verticalTextSpacing);

        // 3. Connector and Collimator
        const pipeY = sourceBox.y + sourceBox.h / 2;
        const pipeGap = 5;
        // Connector pipe
        ctx.beginPath();
        ctx.moveTo(sourceBox.x + sourceBox.w, pipeY - pipeGap);
        ctx.lineTo(sourceBox.x + sourceBox.w + 30, pipeY - pipeGap);
        ctx.moveTo(sourceBox.x + sourceBox.w, pipeY + pipeGap);
        ctx.lineTo(sourceBox.x + sourceBox.w + 30, pipeY + pipeGap);
        ctx.stroke();
        
        // Collimator slits
        const collimatorX = sourceBox.x + sourceBox.w + 40;
        const slitHeight = 60;
        ctx.beginPath();
        ctx.moveTo(collimatorX, pipeY - slitHeight / 2);
        ctx.lineTo(collimatorX, pipeY + slitHeight / 2);
        ctx.moveTo(collimatorX + 10, pipeY - slitHeight / 2);
        ctx.lineTo(collimatorX + 10, pipeY + slitHeight / 2);
        ctx.moveTo(collimatorX + 20, pipeY - slitHeight / 2);
        ctx.lineTo(collimatorX + 20, pipeY + slitHeight / 2);
        ctx.stroke();
        
        // Collimator Label
        ctx.fillText("准直", collimatorX + 10, pipeY + slitHeight / 2 + 30);
        ctx.fillText("狭缝", collimatorX + 10, pipeY + slitHeight / 2 + 55);

        // 4. Atomic Beam
        drawBeamArrow(ctx, sourceBox.x + sourceBox.w, pipeY, 480, pipeY, 15);
        ctx.fillText("原子束", 400, pipeY + 30);
        
        // 5. Dimension Line
        const dimY = vacuumBox.y + vacuumBox.h + 40;
        const tickHeight = 10;
        ctx.beginPath();
        // Main line
        ctx.moveTo(vacuumBox.x, dimY);
        ctx.lineTo(vacuumBox.x + vacuumBox.w, dimY);
        // Left tick
        ctx.moveTo(vacuumBox.x, dimY - tickHeight/2);
        ctx.lineTo(vacuumBox.x, dimY + tickHeight/2);
        // Right tick
        ctx.moveTo(vacuumBox.x + vacuumBox.w, dimY - tickHeight/2);
        ctx.lineTo(vacuumBox.x + vacuumBox.w, dimY + tickHeight/2);
        ctx.stroke();
        ctx.fillText("1 m", vacuumBox.x + vacuumBox.w / 2, dimY + 25);
        
        // 6. Figure Caption
        ctx.fillText("热图 3.19.1", canvas.width / 2, canvas.height - 50);

    </script>
</body>
</html>